#ifndef INFILTRATION_HPP
#define INFILTRATION_HPP

#include "meshTypes_fwd.hpp"
#include "solverBaseTypes_fwd.hpp"
#include "sweSolver.hpp"
#include <experimental/memory>

namespace hms
{

template<typename MeshType>
struct GreenAmpt {
private:
	std::experimental::observer_ptr<const SWESolver<MeshType>> m_solver {nullptr};

public:
	GreenAmpt() = default;

	GreenAmpt( const SWESolver<MeshType>& solverArg ){
		solver( solverArg );
	}

	const SWESolver<MeshType>& solver() const {
		assert( m_solver && "Dereferencing nullptr!" );
		return *m_solver;
	}
	void solver( const SWESolver<MeshType>& solverArg ){
		m_solver = std::experimental::make_observer( &solverArg );
	}

	void operator() (ArrayXXs& vals){
		vals = 0;
	}
};

template<typename MeshType>
void setInfiltrationCallable( SWESolver<MeshType>& solver ){
	if ( solver.useInfiltration() ){
		auto greenAmpt { GreenAmpt(solver) };
		SourceField<NonUniform, MeshType> infiltration {
			solver.mesh(), std::move(greenAmpt), 1
		};
		infiltration.updateValues();
		solver.i() = std::move(infiltration);
		
		// std::visit( [&](const auto& infiltration){
		// 	printAsStructMesh( infiltration.values(), solver.mesh() );
		// }, solver.i() );
	}
}

} // namespace hms

#endif